package com.tenebrous.jestic.job;

import com.tenebrous.jestic.enums.InstanceStatusEnum;
import com.tenebrous.jestic.server.AbstractInstanceContext;
import com.tenebrous.jestic.server.Instance;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Project: jestic-server
 * @Package: com.tenebrous.jestic.job
 * @Author: zhangya
 * @CreateTime: 2023-05-31  17:11
 * @Version: 1.0.0
 */
@Slf4j
@Component
public class ServerJob {

    @Resource
    private AbstractInstanceContext applicationContext;

    @Scheduled(cron = "0 */1 * * * ?")
    public void ScanInstancesWithoutHeartbeat() {
        List<Instance> instances = applicationContext.getInstance();
        List<Instance> collect = instances.stream().filter(x -> x.getRecentlyAuth() != 0).collect(Collectors.toList());
        log.info("jestic current number of surviving instances:[{}]", instances.size());
        Date date = new Date();
        for (Instance instance : collect) {
            Long recentlyAuth = instance.getRecentlyAuth() + 120000;
            Long now = date.getTime();
            if (recentlyAuth - now <= 0) {
                instance.setToken("");
                instance.setRecentlyAuth(new Date().getTime());
                instance.setInstanceStatus(InstanceStatusEnum.OFFLINE);
                instance.setExpireTime(0L);
                instance.setTimes(0);
                applicationContext.flushInstance(instance);
                log.info("jestic The service has not received any heartbeat from instance [{}] for two consecutive minutes. The instance has been offline and will be removed in a few minutes", instance.getInstanceId());
            }
        }
    }

    @Scheduled(cron = "0 */1 * * * ?")
    public void RemoveInstances() {
        List<Instance> instances = applicationContext.getInstance();
        List<Instance> instanceList = instances.stream().filter(x -> x.getInstanceStatus() == InstanceStatusEnum.OFFLINE).collect(Collectors.toList());
        log.info("jestic offline instance num :[{}]", instanceList.size());
        for (Instance instance : instanceList) {
            // 移除实例
            applicationContext.removeInstance(instance);
            log.info("jestic instance [{}] has been forcibly removed from the registry because it has not sent a heartbeat for a long time", instance.getInstanceId());
        }
    }

}
